package com.shop.loan.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shop.loan.mapper.*;
import com.shop.loan.model.*;
import com.shop.loan.model.common.Code;
import com.shop.loan.model.common.ResResult;
import com.shop.loan.model.common.ResResultByCiWei;
import com.shop.loan.model.entity.*;
import com.shop.loan.model.enums.PlatformType;
import com.shop.loan.model.enums.ServiceType;
import com.shop.loan.model.enums.UserStatus;
import com.shop.loan.model.vo.*;
import com.shop.loan.qiniu.QiNiuUtil;
import com.shop.loan.redis.RedisCache;
import com.shop.loan.redis.RedisUtil;
import com.shop.loan.rentaldata.RentalDataUtil;
import com.shop.loan.rentaldata.RentalPayUtil;
import com.shop.loan.service.*;
import com.shop.loan.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import xyz.erupt.upms.util.IpUtil;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Resource
    RedisUtil redisUtil;

    @Resource
    SysMsgUtil sysMsgUtil;

    @Resource
    ChannelService channelService;

    @Value("${sys.defaultChannelId}")
    private Long defaultChannelId;

    @Value("${sys.maxPhoneNum}")
    private Integer maxPhoneNum;

    @Value("${sys.requestUrl}")
    private String requestUrl;

    @Value("${sys.urlByH5}")
    private String urlByH5;

    @Value("${api.qiniu.fileDomainByQn}")
    private String fileDomainByQn;

    @Value("${sys.file.path}")
    private String filePath;

    @Value("${api.service.url}")
    private String serviceUrl;

    @Resource
    UserByMybatisMapper userByMybatisMapper;

    @Resource
    MachineRuleService machineRuleService;

    @Resource
    UserLoginLogByMybatisMapper userLoginLogByMybatisMapper;

    @Resource
    EruptUserByMybatisMapper eruptUserByMybatisMapper;

    @Resource
    LoanOrderByMybatisMapper loanOrderByMybatisMapper;

    @Resource
    UserBankByMybatisMapper userBankByMybatisMapper;

    @Resource
    RentalDataUtil rentalDataUtil;

    @Resource
    RentalPayUtil rentalPayUtil;

    @Resource
    UserInfoByMybatisMapper userInfoByMybatisMapper;

    @Resource
    UserContactByMybatisMapper userContactByMybatisMapper;

    @Resource
    UserAuthLogByMybatisMapper userAuthLogByMybatisMapper;

    @Resource
    ChannelByMybatisMapper channelByMybatisMapper;

    @Resource
    EruptUserDataService eruptUserDataService;

    @Resource
    UserAddressBookByMybatisMapper userAddressBookByMybatisMapper;

    @Resource
    UserCallLogByMybatisMapper userCallLogByMybatisMapper;

    @Resource
    RedisCache redisCache;

    @Resource
    QiNiuUtil qiNiuUtil;

    @Resource
    Util util;

    @Resource
    AsyncService asyncService;

    @Override
    public ResResult getPicCode(UserLoginVo userLoginVo) {
        if (!StringUtils.hasLength(userLoginVo.getMobile())) {
            return new ResResult(Code.PARAM_LACK);
        }
        ValidateCodeUtil.Validate validate = ValidateCodeUtil.getRandomCode();
        redisUtil.setex(RedisCache.userLoginPicCode + userLoginVo.getMobile(), 300, validate.getValue());

        JSONObject dataJs = new JSONObject();
        dataJs.put("picCode", validate.getBase64Str());
        return new ResResult(Code.SUCCESS, dataJs);
    }

    @Transactional
    @Override
    public ResResult getMobileCode(UserLoginVo userLoginVo, boolean isLogin) {
        if (!StringUtils.hasLength(userLoginVo.getMobile())) {
            return new ResResult(Code.PARAM_LACK);
        }
        String mobile = Util.getAesDesStr(userLoginVo.getMobile());
        String picCode = Util.getAesDesStr(userLoginVo.getPicCode());
        if (!StringUtils.hasLength(mobile)) {
            return new ResResult(Code.PARAM_LACK);
        }
        if (isLogin) {
            String redisPicCode = redisUtil.get(RedisCache.userLoginPicCode + mobile);
            if (redisPicCode == null || !redisPicCode.trim().equalsIgnoreCase(picCode)) {
                return new ResResult(Code.PIC_CODE_INVALID);
            }
            //删除图形验证码记录
            redisUtil.del(RedisCache.userLoginPicCode + mobile);
        }

        String redisKey = RedisCache.phoneCodeNum + "_" + mobile + "_" + DateUtil.today();
        String phoneCodeNum = redisUtil.get(redisKey);
        if (phoneCodeNum != null && maxPhoneNum != null && Integer.parseInt(phoneCodeNum) > maxPhoneNum) {
            return new ResResult(Code.PHONE_NUMBER_MAX);
        }
        boolean status = sysMsgUtil.sendVerifyCode(mobile);
        if (status) {
            /**
             * 今日短信数量+1
             */
            redisUtil.incrBy(redisKey, 1);
            return new ResResult(Code.SUCCESS);
        }
        return new ResResult(Code.FAIL);
    }

    @Override
    public ResResult loginByCode(UserLoginVo userLoginVo) {
        String mobile = Util.getAesDesStr(userLoginVo.getMobile());
//        String msgCode = Util.getAesDesStr(userLoginVo.getMsgCode());
        String msgCode = userLoginVo.getCode();
        if (!StringUtils.hasText(msgCode)) {
            return new ResResult(Code.PHONE_CODE_INVALID);
        }

        if (!StringUtils.hasLength(mobile)) {
            return new ResResult(Code.MOBILE_INVALID);
        }
        boolean status = sysMsgUtil.checkVerifyCode(mobile, msgCode);
        if (!status) {
            return new ResResult(Code.CODE_ERROR);
        }
        UserByMybatis user = userByMybatisMapper.selectByMobile(mobile);
        if (user == null || user.getId() == null) {
            user = new UserByMybatis();
            if (userLoginVo.getExpectQuota() != null) {
                user.setExpectQuota(userLoginVo.getExpectQuota());
                user.setExpectDay(userLoginVo.getExpectDay());
            }
            user.setIdentityAuthStatus(false);
            user.setContactAuthStatus(false);
            user.setBankAuthStatus(false);
            user.setMobile(mobile);
            user.setMachineStatus(true);
            user.setUserStatus(UserStatus.normal.getType());
            user.setCreateOrder(false);
            user.setOrderEndNum(0);
            user.setIsDelete(false);
            user.setCreateTime(new Date());
            user.setRegisterIp(userLoginVo.getOpIp());
            user.setChannelId(defaultChannelId);
            user.setName(Util.getUsName(mobile));
            if (StringUtils.hasLength(userLoginVo.getCode())) {
                //渠道注册
                Channel channel = channelService.getChannelByCode(userLoginVo.getCode());
                if (channel != null && channel.getStatus() != null && channel.getStatus()) {
                    user.setChannelId(channel.getId());
                }
            }
            redisUtil.hset(RedisCache.registerMobileMap, mobile, "1");
            userByMybatisMapper.insertSelective(user);

            //分配客服
            eruptUserDataService.allotServiceByBefore(ServiceType.before_service, user.getId());
        } else {
            if (user.getUserStatus() != UserStatus.normal.getType().intValue()) {
                return new ResResult(Code.ACCOUNT_STATUS_ERROR);
            }
        }
        //插入登录记录
        UserLoginLogByMybatis userLoginLogByMybatis = new UserLoginLogByMybatis();
        if (userLoginVo.getDeviceInfo() != null && JSON.isValidObject(userLoginVo.getDeviceInfo())) {
            JSONObject deviceInfoJs = JSON.parseObject(userLoginVo.getDeviceInfo());
            userLoginLogByMybatis.setDeviceInfo(deviceInfoJs.getString("deviceModel") + " " + deviceInfoJs.getString("system"));
            userLoginLogByMybatis.setDeviceId(deviceInfoJs.getString("deviceId"));
        }
        userLoginLogByMybatis.setUserId(user.getId());
        userLoginLogByMybatis.setCreateTime(new Date());
        userLoginLogByMybatis.setIp(userLoginVo.getOpIp());
        userLoginLogByMybatis.setPlatform(userLoginVo.getPFrom());
        userLoginLogByMybatisMapper.insertSelective(userLoginLogByMybatis);

        String token = MD5.create().digestHex(UUID.randomUUID() + user.getMobile());
        redisUtil.set(RedisCache.rentalUserLogin + token, JSON.toJSONString(user));
        return new ResResult(Code.SUCCESS, detail(new UserLoginVo(user.getId())), token);
    }


    /**
     * 一键登录
     *
     * @param mobile
     * @param channelId
     * @param platform
     * @return
     */
    public ResResult loginByOneKey(String mobile, Long channelId, String platform, String ip) {
        UserByMybatis user = userByMybatisMapper.selectByMobile(mobile);
        if (user == null || user.getId() == null) {
            user = new UserByMybatis();
            user.setIdentityAuthStatus(false);
            user.setContactAuthStatus(false);
            user.setBankAuthStatus(false);
            user.setMobile(mobile);
            user.setMachineStatus(true);
            user.setUserStatus(UserStatus.normal.getType());
            user.setCreateOrder(false);
            user.setOrderEndNum(0);
            user.setIsDelete(false);
            user.setCreateTime(new Date());
            user.setChannelId(channelId);
            user.setName(Util.getUsName(mobile));
            user.setRegisterIp(ip);
            redisUtil.hset(RedisCache.registerMobileMap, mobile, "1");
            userByMybatisMapper.insertSelective(user);
        }
        //插入登录记录
        UserLoginLogByMybatis userLoginLogByMybatis = new UserLoginLogByMybatis();
        userLoginLogByMybatis.setDeviceId(UUID.randomUUID().toString());
        userLoginLogByMybatis.setDeviceInfo(platform);
        userLoginLogByMybatis.setUserId(user.getId());
        userLoginLogByMybatis.setIp(ip);
        userLoginLogByMybatis.setCreateTime(new Date());
        userLoginLogByMybatis.setPlatform(platform);
        userLoginLogByMybatisMapper.insertSelective(userLoginLogByMybatis);

        String token = MD5.create().digestHex(UUID.randomUUID() + user.getMobile());
        redisUtil.set(RedisCache.rentalUserLogin + token, JSON.toJSONString(user));
        return new ResResult(Code.SUCCESS, detail(new UserLoginVo(user.getId())), token);
    }


    @Override
    public ResResultByCiWei loginByCiWei(String mobile, Long channelId, String platform, String ip) {
        Code code = Code.SUCCESS;
        UserByMybatis user = userByMybatisMapper.selectByMobile(mobile);
        if (user == null || user.getId() == null) {
            user = new UserByMybatis();
            user.setIdentityAuthStatus(false);
            user.setContactAuthStatus(false);
            user.setBankAuthStatus(false);
            user.setMobile(mobile);
            user.setMachineStatus(true);
            user.setUserStatus(UserStatus.normal.getType());
            user.setCreateOrder(false);
            user.setOrderEndNum(0);
            user.setIsDelete(false);
            user.setCreateTime(new Date());
            user.setChannelId(channelId);
            user.setName(Util.getUsName(mobile));
            user.setRegisterIp(ip);
            redisUtil.hset(RedisCache.registerMobileMap, mobile, "1");
            userByMybatisMapper.insertSelective(user);
        }
        //插入登录记录
        UserLoginLogByMybatis userLoginLogByMybatis = new UserLoginLogByMybatis();
        userLoginLogByMybatis.setDeviceId(UUID.randomUUID().toString());
        userLoginLogByMybatis.setDeviceInfo(platform);
        userLoginLogByMybatis.setUserId(user.getId());
        userLoginLogByMybatis.setIp(ip);
        userLoginLogByMybatis.setCreateTime(new Date());
        userLoginLogByMybatis.setPlatform(platform);
        userLoginLogByMybatisMapper.insertSelective(userLoginLogByMybatis);

        String token = MD5.create().digestHex(UUID.randomUUID() + user.getMobile());
        redisUtil.set(RedisCache.rentalUserLogin + token, JSON.toJSONString(user));
        return new ResResultByCiWei(code, token);
    }

    @Override
    public UserByMybatis detail(UserLoginVo userLoginVo) {
        UserByMybatis detailUser = userByMybatisMapper.selectByPrimaryKey(userLoginVo.getOpId());
        if (detailUser == null) {
            return new UserByMybatis();
        }
        detailUser.setIdCardPicFront(null);
        detailUser.setIdCardPicBack(null);
        detailUser.setUserCheckRes(null);
        detailUser.setCardAddress(null);
        detailUser.setCardNum(Util.DesensitizedIdCardNum(detailUser.getCardNum()));
        detailUser.setMobile(Util.DesensitizedMobile(detailUser.getMobile()));
        detailUser.setLoanOrder(loanOrderByMybatisMapper.selectOrderByIng(userLoginVo.getOpId()));
        detailUser.setServiceUrl(serviceUrl);
        detailUser.setOrderIngNum(loanOrderByMybatisMapper.selectIngByUser(userLoginVo.getOpId()));
        detailUser.setOrderWaitPay(loanOrderByMybatisMapper.selectWaitPayByUser(userLoginVo.getOpId()));
        detailUser.setOssByQnUrl(fileDomainByQn);
        //客服二维码
        if (detailUser.getServiceUserId() != null) {
            EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(detailUser.getServiceUserId());
            if (eruptUserByMybatis != null) {
                detailUser.setServiceQrCode(eruptUserByMybatis.getServiceQrCode());
            }
        }
        return detailUser;
    }


    @Override
    public ResResult createIdentityUrl(CreateAuthVo createAuthVo) {
        if (!StringUtils.hasLength(createAuthVo.getCardName()) || !StringUtils.hasLength(createAuthVo.getCardNum())
                || !StringUtils.hasLength(createAuthVo.getIdCardPicBack())
                || !StringUtils.hasLength(createAuthVo.getIdCardPicFront())) {
            return new ResResult(Code.PARAM_LACK);
        }
        if (!IdcardUtil.isValidCard(createAuthVo.getCardNum())) {
            return new ResResult(Code.ID_CARD_INVALID);
        }
        if (createAuthVo.getOcrInfoByFront() == null || "{}".trim().equals(createAuthVo.getOcrInfoByFront())) {
            return new ResResult(Code.ID_CARD_FRONT_ERROR);
        }
        if (createAuthVo.getOcrInfoByBack() == null || "{}".trim().equals(createAuthVo.getOcrInfoByBack())) {
            return new ResResult(Code.ID_CARD_BACK_ERROR);
        }

        UserByMybatis user = userByMybatisMapper.selectByPrimaryKey(createAuthVo.getOpId());
        if (user == null || !StringUtils.hasLength(user.getMobile())) {
            return new ResResult(Code.RATE_HIGH);
        }

//        String redirectUrl = urlByH5 + "pagesIndex/contacts/add";
        String redirectUrl = urlByH5 + "pages/member/contacts/add";
        if (PlatformType.app.getType().trim().equals(createAuthVo.getPFrom())) {
            redirectUrl = requestUrl + "/success_1.html";
        }
        JSONObject authInfoJs = rentalDataUtil.personAuthFace(createAuthVo.getCardName(), createAuthVo.getCardNum(), user.getMobile(), redirectUrl);
        if (authInfoJs == null) {
            return new ResResult(Code.AUTH_ERROR);
        }
        //判断身份证是否已存在
        Integer registerNum = userByMybatisMapper.selectByCardNum(createAuthVo.getCardNum());
        if (registerNum != null && registerNum > 0) {
            return new ResResult(Code.IDEN_EXITS);
        }

        UserAuthLogByMybatis userAuthLogByMybatis = new UserAuthLogByMybatis();
        userAuthLogByMybatis.setUserId(createAuthVo.getOpId());
        userAuthLogByMybatis.setIdCardPicBack("/" + createAuthVo.getIdCardPicBack());
        userAuthLogByMybatis.setIdCardPicFront("/" + createAuthVo.getIdCardPicFront());
        userAuthLogByMybatis.setCardName(createAuthVo.getCardName());
        userAuthLogByMybatis.setCardNum(createAuthVo.getCardNum());
        userAuthLogByMybatis.setOcrInfoByFront(createAuthVo.getOcrInfoByFront());
        userAuthLogByMybatis.setOcrInfoByBack(createAuthVo.getOcrInfoByBack());
        userAuthLogByMybatis.setAuthUrl(authInfoJs.getString("faceUrl"));
        userAuthLogByMybatis.setAuthFlowId(authInfoJs.getString("serialNo"));
        userAuthLogByMybatis.setCreateTime(new Date());
        if (JSON.isValidObject(createAuthVo.getOcrInfoByFront())) {
            JSONObject ocrFrontJs = JSON.parseObject(createAuthVo.getOcrInfoByFront());
            if (ocrFrontJs.containsKey("info")) {
                userAuthLogByMybatis.setIdCardAddress(ocrFrontJs.getJSONObject("info").getString("address"));
            }
        }
        userAuthLogByMybatisMapper.insertSelective(userAuthLogByMybatis);
        return new ResResult(Code.SUCCESS, authInfoJs);
    }


    @Override
    public ResResult personAuthFaceSuccess(CreateAuthVo createAuthVo) {
        if (!StringUtils.hasText(createAuthVo.getSerialNo())) {
            return new ResResult(Code.PARAM_LACK);
        }
        UserAuthLogByMybatis userAuthLogByMybatis = userAuthLogByMybatisMapper.selectByAuthFlowId(createAuthVo.getSerialNo());
        if (userAuthLogByMybatis == null || userAuthLogByMybatis.getId() == null) {
            return new ResResult(Code.PARAM_INVALID);
        }
        if (userAuthLogByMybatis.getSuccessTime() != null) {
            return new ResResult(Code.SUCCESS);
        }
        userAuthLogByMybatis.setSuccessTime(new Date());

        ResResult authRes = rentalDataUtil.personAuthFaceSuccess(createAuthVo.getSerialNo());
        if (authRes.getCode() != Code.SUCCESS.getCode().intValue()) {
            return authRes;
        }
        if (authRes.getData() != null && StringUtils.hasLength(authRes.getData().toString())) {
            JSONObject itemJs = JSON.parseObject(authRes.getData().toString());
            String path = filePath + "/face/";
            //base64图片保存到本地
            path = FileUtil.generateImage(itemJs.getString("data"), path, userAuthLogByMybatis.getCardNum() + "_" + itemJs.getString("fileName"));
            userAuthLogByMybatis.setFacePhoto(qiNiuUtil.upLoadByFilePath(path, itemJs.getString("fileName")));
        }
        userAuthLogByMybatisMapper.updateByPrimaryKeySelective(userAuthLogByMybatis);

        UserByMybatis user = new UserByMybatis();
        user.setId(userAuthLogByMybatis.getUserId());
        user.setName(userAuthLogByMybatis.getCardName());
        user.setCardName(userAuthLogByMybatis.getCardName());
        user.setCardNum(userAuthLogByMybatis.getCardNum());
        user.setIdCardPicBack(userAuthLogByMybatis.getIdCardPicBack());
        user.setIdCardPicFront(userAuthLogByMybatis.getIdCardPicFront());
        user.setIdentityAuthStatus(true);
        user.setCardAddress(userAuthLogByMybatis.getIdCardAddress());

//        {"validity":{"birthday":true,"number":true,"address":true,"sex":true,"name":true},"info":{"number":"500236199108063510","address":"重庆市奉节县夔州街道魏家社区1组228号","month":"08","nation":"汉","year":"1991","sex":"男","name":"白东奎","day":"06"}}
        if (StringUtils.hasText(userAuthLogByMybatis.getOcrInfoByFront())) {
            //性别
            JSONObject ocrInfoJs = JSON.parseObject(userAuthLogByMybatis.getOcrInfoByFront());
            if (ocrInfoJs != null && ocrInfoJs.containsKey("info")) {
                String sex = ocrInfoJs.getJSONObject("info").getString("sex");
                if ("男".trim().equals(sex)) {
                    user.setGender(1);
                } else if ("女".trim().equals(sex)) {
                    user.setGender(2);
                }
            }
        }
        //年龄
        user.setAge(IdcardUtil.getAgeByIdCard(userAuthLogByMybatis.getCardNum()));
        userByMybatisMapper.updateByPrimaryKeySelective(user);
        return new ResResult(Code.SUCCESS);
    }

    @Override
    public Boolean rdUserCheck(UserByMybatis user) {
        String mobile1 = null, mobile2 = null;
        //获取通讯录
        List<UserContactByMybatis> userContactByMybatisList = userContactByMybatisMapper.selectByUser(user.getId());
        if (userContactByMybatisList != null && userContactByMybatisList.size() > 0) {
            for (int i = 0; i < userContactByMybatisList.size(); i++) {
                if (i == 0) {
                    mobile1 = userContactByMybatisList.get(i).getMobile();
                } else if (i == 1) {
                    mobile2 = userContactByMybatisList.get(i).getMobile();
                }
            }
        }

        JSONObject rdRes = rentalDataUtil.getRdCheck(user.getCardName(), user.getMobile(), user.getCardNum(), mobile1, mobile2);
        if (rdRes == null) {
            return true;
        }
        if (!rdRes.containsKey("rejectStatus")) {
            rdRes.put("rejectStatus", false);
        }
        boolean checkStatus = true;
        if (rdRes.getBoolean("overdueStatus") || rdRes.getBoolean("blackStatus") || rdRes.getBoolean("ekaStatus") || rdRes.getBoolean("rejectStatus")) {
            //命中
            checkStatus = false;
        }
        UserByMybatis updateUser = new UserByMybatis();
        updateUser.setId(user.getId());
        updateUser.setMachineStatus(checkStatus);
        updateUser.setUserCheckRes(rdRes.toJSONString());
        userByMybatisMapper.updateByPrimaryKeySelective(updateUser);
        return checkStatus;
    }


    @Override
    public ResResult bankAuthGetCode(CreateAuthVo createAuthVo) {
        if (!StringUtils.hasLength(createAuthVo.getBankNo())) {
            return new ResResult(Code.PARAM_LACK);
        }
        UserByMybatis userByMybatis = userByMybatisMapper.selectByPrimaryKey(createAuthVo.getOpId());
        if (userByMybatis == null || !StringUtils.hasLength(userByMybatis.getCardNum())) {
            return new ResResult(Code.USER_IDENTITY_AUTH_LACK);
        }
        /**
         * 调用三方支付接口
         */
        String outTradeNo = Util.getOutTradeNo();
        RentalPayVo rentalPayVo = new RentalPayVo();
        rentalPayVo.setIdNo(userByMybatis.getCardNum());
        rentalPayVo.setMobile(createAuthVo.getPhone());
        rentalPayVo.setRealName(userByMybatis.getCardName());
        rentalPayVo.setCardNo(createAuthVo.getBankNo());
        rentalPayVo.setOrderNo(outTradeNo);
        rentalPayVo.setUserId(util.getUserId(userByMybatis.getId()));
        return rentalPayUtil.signing(rentalPayVo);
    }

    @Override
    public ResResult bankAuth(CreateAuthVo createAuthVo) {
        if (!StringUtils.hasText(createAuthVo.getBankNo()) || !StringUtils.hasText(createAuthVo.getValidateCode())) {
            return new ResResult(Code.PARAM_LACK);
        }
        RentalPayVo rentalPayVo = new RentalPayVo();
        rentalPayVo.setOrderNo(createAuthVo.getOrderNo());
        rentalPayVo.setVerifyCode(createAuthVo.getValidateCode());
        ResResult msgRes = rentalPayUtil.signMessage(rentalPayVo);
        if (msgRes.getCode() != Code.SUCCESS.getCode().intValue()) {
            return msgRes;
        }
        if (createAuthVo.getBankName() != null && createAuthVo.getBankName().contains("(")) {
            createAuthVo.setBankName(createAuthVo.getBankName().split("\\(")[0]);
        } else {
            createAuthVo.setBankName(new BankInfoUtil(createAuthVo.getBankNo()).getBankName());
        }
        UserBankByMybatis userBankByMybatis = new UserBankByMybatis();
        userBankByMybatis.setCarNo(createAuthVo.getBankNo());
        userBankByMybatis.setBankName(createAuthVo.getBankName());
        userBankByMybatis.setIsDelete(false);
        userBankByMybatis.setUserId(createAuthVo.getOpId());
        userBankByMybatis.setPhone(createAuthVo.getPhone());
        userBankByMybatis.setBankUrl(createAuthVo.getBankUrl());
        userBankByMybatis.setCreateTime(new Date());
        userBankByMybatis.setProtocol(msgRes.getData().toString());
        userBankByMybatisMapper.insertSelective(userBankByMybatis);

        UserByMybatis updateUser = new UserByMybatis();
        updateUser.setId(createAuthVo.getOpId());
        updateUser.setBankAuthStatus(true);
        userByMybatisMapper.updateByPrimaryKeySelective(updateUser);

        LoanOrderByMybatis loanOrderByMybatis = loanOrderByMybatisMapper.selectOrderByIng(createAuthVo.getOpId());
        if (loanOrderByMybatis != null && loanOrderByMybatis.getId() != null && loanOrderByMybatis.getBankId() == null) {
            LoanOrderByMybatis updateOrder = new LoanOrderByMybatis();
            updateOrder.setId(loanOrderByMybatis.getId());
            updateOrder.setBankId(userBankByMybatis.getId());
            loanOrderByMybatisMapper.updateByPrimaryKeySelective(updateOrder);

            asyncService.notifyCheck(loanOrderByMybatis.getId());
        }
        return new ResResult(Code.SUCCESS);
    }


    @Override
    public ResResult bankList(CreateAuthVo createAuthVo) {
        List<UserBankByMybatis> bankList = userBankByMybatisMapper.selectByUser(createAuthVo.getOpId());
        for (UserBankByMybatis userBankByMybatis : bankList) {
            userBankByMybatis.setPhone(Util.DesensitizedMobile(userBankByMybatis.getPhone()));
            userBankByMybatis.setCarNo(Util.DesensitizedBankNo(userBankByMybatis.getCarNo()));
        }
        return new ResResult(Code.SUCCESS, bankList);
    }


    @Override
    public ResResult bankListByAR(CreateAuthVo createAuthVo) {
        List<UserBankByMybatis> bankList = userBankByMybatisMapper.selectByOrderId(createAuthVo.getOrderId());
        for (UserBankByMybatis userBankByMybatis : bankList) {
            userBankByMybatis.setPhone(Util.DesensitizedMobile(userBankByMybatis.getPhone()));
            userBankByMybatis.setCarNo(Util.DesensitizedBankNo(userBankByMybatis.getCarNo()));
        }
        return new ResResult(Code.SUCCESS, bankList);
    }


    @Override
    public ResResult infoAuth(UserInfoByMybatis userInfo) {
        if (userInfo.getEduLevel() == null || userInfo.getLiveTime() == null || userInfo.getLiveAddress() == null
                || userInfo.getIndustry() == null || userInfo.getSalaryNum() == null || userInfo.getDebtNum() == null
                || userInfo.getMarryStatus() == null) {
            return new ResResult(Code.PARAM_LACK);
        }

        UserInfoByMybatis dbUserInfoByMybatis = userInfoByMybatisMapper.selectByUser(userInfo.getOpId());
        if (dbUserInfoByMybatis != null && dbUserInfoByMybatis.getId() != null) {
            userInfo.setId(dbUserInfoByMybatis.getId());
            userInfoByMybatisMapper.updateByPrimaryKeySelective(userInfo);
        } else {
            userInfo.setUserId(userInfo.getOpId());
            userInfo.setCreateTime(new Date());
            userInfoByMybatisMapper.insertSelective(userInfo);
        }
        UserByMybatis userByMybatis = new UserByMybatis();
        userByMybatis.setId(userInfo.getOpId());
//        userByMybatis.setInfoAuthStatus(true);
        userByMybatisMapper.updateByPrimaryKeySelective(userByMybatis);
        return new ResResult(Code.SUCCESS);
    }

    @Override
    public ResResult contactAuth(UserContactByMybatis userContactByMybatis) {
        if (userContactByMybatis.getName() == null || userContactByMybatis.getMobile() == null || userContactByMybatis.getRelation() == null
                || userContactByMybatis.getName2() == null || userContactByMybatis.getMobile2() == null
                || userContactByMybatis.getRelation2() == null) {
            return new ResResult(Code.PARAM_LACK);
        }
        if (!PhoneUtil.isMobile(userContactByMybatis.getMobile()) || !PhoneUtil.isMobile(userContactByMybatis.getMobile2())) {
            return new ResResult(Code.MOBILE_INVALID);
        }

        userContactByMybatis.setMobile(userContactByMybatis.getMobile().replaceAll(" ", ""));
        userContactByMybatis.setUserId(userContactByMybatis.getOpId());
        userContactByMybatis.setCreateTime(new Date());
        userContactByMybatisMapper.insertSelective(userContactByMybatis);

        UserContactByMybatis userContactByMybatis2 = new UserContactByMybatis();
        userContactByMybatis2.setName(userContactByMybatis.getName2());
        userContactByMybatis2.setMobile(userContactByMybatis.getMobile2().replaceAll(" ", ""));
        userContactByMybatis2.setRelation(userContactByMybatis.getRelation2());
        userContactByMybatis2.setCreateTime(new Date());
        userContactByMybatis2.setUserId(userContactByMybatis.getOpId());
        userContactByMybatisMapper.insertSelective(userContactByMybatis2);

        UserByMybatis userByMybatis = new UserByMybatis();
        userByMybatis.setId(userContactByMybatis.getOpId());
        userByMybatis.setContactAuthStatus(true);
        userByMybatisMapper.updateByPrimaryKeySelective(userByMybatis);

        UserByMybatis dbUser = userByMybatisMapper.selectByPrimaryKey(userContactByMybatis.getOpId());

        SettingByMybatis setting = redisCache.getSetting(false);
        if (setting.getChannelBlack() != null && setting.getChannelBlack() && dbUser.getChannelId() != null && dbUser.getChannelId() == defaultChannelId.intValue()) {
            //自然渠道自动拉黑
            UserByMybatis updateUser = new UserByMybatis();
            updateUser.setId(dbUser.getId());
            updateUser.setMachineStatus(false);
            updateUser.setRemark("自然渠道拒");
            userByMybatisMapper.updateByPrimaryKeySelective(updateUser);
        } else {
            //融担用户校验
            rdUserCheck(dbUser);
            //机审
            machineRuleService.createUpdateMachineReportByASync(dbUser.getId());
        }
        return new ResResult(Code.SUCCESS);
    }


    @Override
    public ResResult del(UploadCallLogVo uploadCallLogVo) {
        UserByMybatis dbUser = userByMybatisMapper.selectByPrimaryKey(uploadCallLogVo.getOpId());
        if (dbUser == null) {
            return new ResResult(Code.SUCCESS);
        }
        LoanOrderByMybatis loanOrderByMybatis = loanOrderByMybatisMapper.selectOrderByIng(dbUser.getId());
        if (loanOrderByMybatis != null && loanOrderByMybatis.getId() != null) {
            return new ResResult(Code.DEL_ORDER_ING);
        }
        UserByMybatis updateUser = new UserByMybatis();
        updateUser.setId(uploadCallLogVo.getOpId());
        updateUser.setMobile(dbUser.getMobile() + Util.prefixDel + DateUtil.now());
        updateUser.setCardNum(dbUser.getCardNum() + Util.prefixDel + DateUtil.now());
        updateUser.setUserStatus(UserStatus.logout.getType());
        userByMybatisMapper.updateByPrimaryKeySelective(updateUser);
        return new ResResult(Code.SUCCESS);
    }

    @Override
    public ResResult uploadAddressBook(UploadAddressBookVo uploadAddressBookVo) {
        if (uploadAddressBookVo == null || !JSON.isValidArray(uploadAddressBookVo.getAddressBooks())) {
            return new ResResult(Code.PARAM_LACK);
        }
        List<UserAddressBookByMybatis> addressBookByMybatisList = JSON.parseArray(uploadAddressBookVo.getAddressBooks(), UserAddressBookByMybatis.class);
        if (addressBookByMybatisList.size() <= 0) {
            return new ResResult(Code.SUCCESS);
        }
        for (UserAddressBookByMybatis userAddressBook : addressBookByMybatisList) {
            if (!StringUtils.hasText(userAddressBook.getMobile())) {
                continue;
            }
            userAddressBook.setMobile(userAddressBook.getMobile().replaceAll(" ", ""));
            userAddressBook.setCreateTime(new Date());
            userAddressBook.setIsRegister(redisCache.checkMobileIsRegister(userAddressBook.getMobile()));
            userAddressBook.setUserId(uploadAddressBookVo.getOpId());
        }
        userAddressBookByMybatisMapper.batchInsert(addressBookByMybatisList);
        return new ResResult(Code.SUCCESS);
    }

    @Override
    public ResResult uploadCallLog(UploadCallLogVo uploadCallLogVo) {
        if (uploadCallLogVo == null || !JSON.isValidArray(uploadCallLogVo.getCallLogs())) {
            return new ResResult(Code.PARAM_LACK);
        }
        List<UserCallLogByMybatis> userCallLogByMybatisList = JSON.parseArray(uploadCallLogVo.getCallLogs(), UserCallLogByMybatis.class);
        if (userCallLogByMybatisList.size() <= 0) {
            return new ResResult(Code.SUCCESS);
        }
        for (UserCallLogByMybatis userCallLogByMybatis : userCallLogByMybatisList) {
            userCallLogByMybatis.setCreateTime(new Date());
            userCallLogByMybatis.setIsRegister(redisCache.checkMobileIsRegister(userCallLogByMybatis.getMobile()));
            userCallLogByMybatis.setUserId(uploadCallLogVo.getOpId());
        }
        userCallLogByMybatisMapper.batchInsert(userCallLogByMybatisList);
        return new ResResult(Code.SUCCESS);
    }


    @Override
    public ResResult getAddressBook(UserReportVo userReportVo) {
        if (userReportVo.getUserId() == null) {
            return new ResResult(Code.PARAM_INVALID);
        }
        UserAddressBookByMybatis userAddressBookByMybatis = new UserAddressBookByMybatis();
        userAddressBookByMybatis.setUserId(userReportVo.getUserId());
        List<UserAddressBookByMybatis> userAddressBookByMybatisList = userAddressBookByMybatisMapper.selectList(userAddressBookByMybatis);
        if (userAddressBookByMybatisList != null && userAddressBookByMybatisList.size() > 0) {
            for (UserAddressBookByMybatis addressBookByMybatis : userAddressBookByMybatisList) {
                addressBookByMybatis.setMobile(Util.DesensitizedMobile(addressBookByMybatis.getMobile()));
            }
        }
        return new ResResult(Code.SUCCESS, userAddressBookByMybatisList);
    }

    @Override
    public ResResult getCallLog(UserReportVo userReportVo) {
        if (userReportVo.getUserId() == null) {
            return new ResResult(Code.PARAM_INVALID);
        }
        UserCallLogByMybatis userCallLogByMybatis = new UserCallLogByMybatis();
        userCallLogByMybatis.setUserId(userReportVo.getUserId());
        List<UserCallLogByMybatis> userCallLogByMybatisList = userCallLogByMybatisMapper.selectList(userCallLogByMybatis);
        if (userCallLogByMybatisList != null && userCallLogByMybatisList.size() > 0) {
            for (UserCallLogByMybatis userCallLogByMybatis1 : userCallLogByMybatisList) {
                userCallLogByMybatis1.setMobile(Util.DesensitizedMobile(userCallLogByMybatis1.getMobile()));
            }
        }
        return new ResResult(Code.SUCCESS, userCallLogByMybatisList);
    }

    @Override
    public ResResult getLoginLog(UserReportVo userReportVo) {
        JSONObject dataJs = new JSONObject();
//        IpUtil.getCityInfo()
        List<UserLoginLogByMybatis> userLoginLog = userLoginLogByMybatisMapper.selectListByUser(userReportVo.getUserId());
        if (userLoginLog != null && userLoginLog.size() > 0) {
            for (UserLoginLogByMybatis userLoginLogByMybatis : userLoginLog) {
                if (userLoginLogByMybatis != null && StringUtils.hasLength(userLoginLogByMybatis.getIp())) {
                    userLoginLogByMybatis.setIpAddress(IpUtil.getCityInfo(userLoginLogByMybatis.getIp()));
                }
            }
        }

        List<UserLoginLogByMybatis> deviceLoginLog = userLoginLogByMybatisMapper.selectListByDevice(userReportVo.getUserId());
        if (deviceLoginLog != null && deviceLoginLog.size() > 0) {
            for (UserLoginLogByMybatis userLoginLogByMybatis : deviceLoginLog) {
                if (userLoginLogByMybatis != null && StringUtils.hasLength(userLoginLogByMybatis.getIp())) {
                    userLoginLogByMybatis.setIpAddress(IpUtil.getCityInfo(userLoginLogByMybatis.getIp()));
                }
            }
        }

        dataJs.put("userLoginLog", userLoginLog);
        dataJs.put("deviceLoginLog", deviceLoginLog);
        return new ResResult(Code.SUCCESS, dataJs);
    }

    @Override
    public ResResult getProduct(CreateAuthVo createAuthVo) {
//        UserByMybatis userByMybatis = userByMybatisMapper.selectByPrimaryKey(createAuthVo.getOpId());
//        Integer conditionNumber = userByMybatis.getOrderEndNum() == null ? 0 : userByMybatis.getOrderEndNum();
//        ChannelByMybatis channel = channelByMybatisMapper.selectByPrimaryKey(userByMybatis.getChannelId());
//
//        List<Long> productIds = new ArrayList<>();
//        productIds.add(-1L);
//        if (channel != null) {
//            List<Long> ids = productChannelByMybatisMapper.selectListByChannel(channel.getId());
//            if (ids != null && ids.size() > 0) {
//                productIds.addAll(ids);
//            }
//        }
//        List<Long> userProductList = productByMybatisMapper.selectListByUser(productIds, conditionNumber);
//
//        Integer successNum = loanOrderByMybatisMapper.selectNumByLoanSuccess(createAuthVo.getOpId());
//        successNum = successNum == null ? 0 : successNum;
//
//        List<ProductByMybatis> productList = productByMybatisMapper.selectList(productIds);
//        for (ProductByMybatis productByMybatis : productList) {
//            if (userProductList.contains(productByMybatis.getId())) {
//                productByMybatis.setSelect(true);
//            } else {
//                productByMybatis.setSelect(false);
//            }
//            BigDecimal rateMoney = Util.getRateMoney(productByMybatis.getMoney(), productByMybatis.getYearRate(), productByMybatis.getLoanDay());
//            productByMybatis.setRateMoney(rateMoney);
//        }
        return new ResResult(Code.SUCCESS);
    }

    public ResResult getOcrInfo(OcrVo ocrVo) {
        JSONObject resultJs = rentalDataUtil.getOcrInfo(ocrVo);
        if (resultJs != null) {
            return new ResResult(Code.SUCCESS, resultJs);
        }
        return new ResResult(Code.OCR_FAIL);
    }

    @Override
    public ResResult getOcrByBank(OcrVo ocrVo) {
        if (!StringUtils.hasText(ocrVo.getUrl())) {
            return new ResResult(Code.PARAM_LACK);
        }
        JSONObject resultJs = rentalDataUtil.getOcrByBank(ocrVo.getUrl());
        if (resultJs != null) {
            return new ResResult(Code.SUCCESS, resultJs);
        }
        return new ResResult(Code.OCR_FAIL);
    }

    @Override
    public ResResult detailByOrderId(LoanOrderVo orderVo) {
        if (orderVo.getOrderId() == null && orderVo.getUserId() == null) {
            return new ResResult(Code.PARAM_LACK);
        }
        UserByMybatis user;
        if (orderVo.getOrderId() != null) {
            LoanOrderByMybatis userOrderByMybatis = loanOrderByMybatisMapper.selectByPrimaryKey(orderVo.getOrderId());
            if (userOrderByMybatis == null || userOrderByMybatis.getId() == null) {
                return new ResResult(Code.PARAM_INVALID);
            }
            user = userByMybatisMapper.selectByPrimaryKey(userOrderByMybatis.getUserId());
        } else {
            user = userByMybatisMapper.selectByPrimaryKey(orderVo.getUserId());
        }

        if (user == null) {
            return new ResResult(Code.PARAM_INVALID);
        }

        user.setBlackStatus(true);
        user.setContactStatus(true);
        if (user.getUserCheckRes() != null && JSON.isValidObject(user.getUserCheckRes())) {
            JSONObject userCheckJs = JSON.parseObject(user.getUserCheckRes());
            if (!userCheckJs.containsKey("rejectStatus")) {
                userCheckJs.put("rejectStatus", false);
            }
            if (userCheckJs.getBoolean("ekaStatus") || userCheckJs.getBoolean("blackStatus") || userCheckJs.getBoolean("overdueStatus") || userCheckJs.getBoolean("rejectStatus")) {
                user.setBlackStatus(false);
            }
            if (userCheckJs.getBoolean("contactStatus")) {
                user.setContactStatus(false);
            }
        }

        //人脸照片
        UserAuthLogByMybatis userAuthLogByMybatis = userAuthLogByMybatisMapper.selectByUserId(user.getId());
        if (userAuthLogByMybatis != null) {
            user.setFacePhoto(userAuthLogByMybatis.getFacePhoto());
        }
        user.setCreateTimeStr(DateUtil.formatDateTime(user.getCreateTime()));
        //下单定位
//        user.setLocationAddress(userOrderByMybatis.getLocationAddress());
        //渠道名称
        if (user.getChannelId() != null) {
            ChannelByMybatis channel = channelByMybatisMapper.selectByPrimaryKey(user.getChannelId());
            if (channel != null) {
                user.setChannelName(channel.getName());
            }
        }
        //紧急联系人
        user.setContactByMybatisList(userContactByMybatisMapper.selectByUser(user.getId()));
        //绑定银行卡
        List<UserBankByMybatis> bankList = userBankByMybatisMapper.selectByUser(user.getId());
        if (bankList != null) {
            for (UserBankByMybatis userBankByMybatis : bankList) {
                userBankByMybatis.setProtocol(null);
            }
            user.setBankList(bankList);
        }

        return new ResResult(Code.SUCCESS, user);
    }

    @Override
    public ResResult addContract(UserContactByMybatis userContactByMybatis) {
        if (!StringUtils.hasText(userContactByMybatis.getMobile()) || !StringUtils.hasText(userContactByMybatis.getName()) || userContactByMybatis.getRelation() == null || userContactByMybatis.getUserId() == null) {
            return new ResResult(Code.PARAM_LACK);
        }
        userContactByMybatisMapper.insertSelective(userContactByMybatis);
        return new ResResult(Code.SUCCESS);
    }


    @Override
    public ResResult loginByGetMobile(UserLoginVo userLoginVo) {
        ResResult resResult = rentalDataUtil.loginByGetMobile(userLoginVo.getAccessToken());
        if (resResult.getCode().intValue() != Code.SUCCESS.getCode()) {
            return resResult;
        }
        JSONObject resJs = JSON.parseObject(resResult.getData().toString());
        if (resJs == null || !resJs.containsKey("getMobileResultDTO")) {
            return new ResResult(Code.FAIL);
        }
        String mobile = resJs.getJSONObject("getMobileResultDTO").getString("mobile");
        if (!StringUtils.hasLength(mobile)) {
            return new ResResult(Code.FAIL);
        }
        Long channelId = defaultChannelId;
        if (StringUtils.hasLength(userLoginVo.getCode())) {
            //渠道注册
            Channel channel = channelService.getChannelByCode(userLoginVo.getCode());
            if (channel != null && channel.getStatus() != null && channel.getStatus()) {
                channelId = channel.getId();
            }
        }
        return loginByOneKey(mobile, channelId, "app-one", userLoginVo.getOpIp());
    }

    @Override
    public ResResult loginByGetAuthToken(UserLoginVo userLoginVo) {
        return rentalDataUtil.loginByGetAuthToken(urlByH5.substring(0, urlByH5.length() - 2), urlByH5.substring(0, urlByH5.length() - 3));
    }

    @Override
    public ResResult loginByGetPhoneWithToken(UserLoginVo userLoginVo) {
        ResResult resResult = rentalDataUtil.loginByGetPhoneWithToken(userLoginVo.getSpToken());
        if (resResult.getCode().intValue() != Code.SUCCESS.getCode()) {
            return resResult;
        }
        JSONObject resJs = JSON.parseObject(resResult.getData().toString());
        if (resJs == null || !resJs.containsKey("data")) {
            return new ResResult(Code.FAIL);
        }
        String mobile = resJs.getJSONObject("data").getString("mobile");
        if (!StringUtils.hasLength(mobile)) {
            return new ResResult(Code.FAIL);
        }
        Long channelId = defaultChannelId;
        if (StringUtils.hasLength(userLoginVo.getCode())) {
            //渠道注册
            Channel channel = channelService.getChannelByCode(userLoginVo.getCode());
            if (channel != null && channel.getStatus() != null && channel.getStatus()) {
                channelId = channel.getId();
            }
        }
        return loginByOneKey(mobile, channelId, "h5-one", userLoginVo.getOpIp());
    }
}
